# coding: utf-8
from PySide6.QtCore import Qt, Signal, QFileInfo
from PySide6.QtGui import QPainter, QPen, QDragEnterEvent, QDropEvent, QMouseEvent, QDesktopServices
from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel, QHBoxLayout, QFileDialog, QSizePolicy

from qfluentwidgets import PrimaryPushButton, FluentIcon, InfoBarIcon, StrongBodyLabel, BodyLabel, setFont,PushButton
from qfluentwidgets import Flyout, FlyoutAnimationType, FlyoutView, FlyoutViewBase


class CustomDropFileWidgetBase(QWidget):
    """ 自定义文件拖放控件基类 """
    suffixes: list[str] = []
    _is_drag_over = False # 标记是否有文件拖拽悬停

    def __init__(self, parent: QWidget | None = None):
        super().__init__(parent)
        self.setAcceptDrops(True)

        self.vBoxLayout = QVBoxLayout(self)
        self.vBoxLayout.setContentsMargins(20, 20, 20, 20) # 增加内边距
        self.vBoxLayout.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.iconLabel = QLabel(self)
        # 使用一个通用的图标，或者后续可以根据子类设置
        # self.iconLabel.setPixmap(FluentIcon.DOCUMENT.icon(64, 64).pixmap(64,64)) # 示例图标
        self.iconLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
        # self.vBoxLayout.addWidget(self.iconLabel) # 图标暂时不添加，与截图不符

        self.titleLabel = StrongBodyLabel(self) # 使用 StrongBodyLabel 增强标题
        self.titleLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        self.vBoxLayout.addWidget(self.titleLabel)

        # self.orLabel = BodyLabel("或者", self)
        # self.orLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
        # self.vBoxLayout.addWidget(self.orLabel)

        self.buttonLayout = QHBoxLayout()
        self.buttonLayout.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.vBoxLayout.addLayout(self.buttonLayout)
        
        # 添加清空文件按钮
        self.clearFileButton = PushButton(FluentIcon.CANCEL, "清空文件", self)
        self.clearFileButton.clicked.connect(self._onClearFileClicked)
        self.clearFileButton.setEnabled(False)  # 默认禁用，当有文件时启用
        
        # 设置最小高度，使其在空状态下也有一定大小
        self.setMinimumHeight(150) # 根据截图调整
        # self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
        self.setObjectName("customDropFileWidget")
        self._apply_style()

    def _onClearFileClicked(self):
        """清空文件按钮点击事件，由子类实现具体逻辑"""
        pass

    def _apply_style(self):
        # 尝试应用类似 qfluentwidgets 的样式
        self.setProperty("border", "1px dashed #d0d0d0") # 使用属性来设置边框，便于样式表控制
        # 可以在这里加载 qss，或者在应用层面统一处理
        # self.setStyleSheet("QWidget#customDropFileWidget { border: 1px dashed gray; border-radius: 5px; }")


    def setTitle(self, text: str):
        if len(text) > 80:
            text = text[:40] + "..." + text[-40:]
        self.titleLabel.setText(text)

    def setSuffixes(self, suffixes: list[str]):
        self.suffixes = [s.lower().strip().lstrip('.') for s in suffixes]
        if self.suffixes:
            # 获取格式列表
            formats = ', '.join(s.upper() for s in self.suffixes)
            self.setTitle(f"支持的格式：{formats}")
        else:
            self.setTitle("将文件拖到此处")

    def canAccept(self, path: str) -> bool:
        if not self.suffixes:
            return True  # 如果未设置后缀，则接受所有文件
        file_info = QFileInfo(path)
        suffix = file_info.suffix().lower()
        return suffix in self.suffixes

    def dragEnterEvent(self, event: QDragEnterEvent):
        print("dragEnterEvent")
        mime_data = event.mimeData()
        if mime_data.hasUrls():
            # 检查至少一个文件是否符合后缀要求
            can_accept_any = False
            for url in mime_data.urls():
                if url.isLocalFile():
                    if self.canAccept(url.toLocalFile()):
                        can_accept_any = True
                        break
            if can_accept_any:
                event.acceptProposedAction()
                self._is_drag_over = True
                self.update() # 触发 paintEvent
            else:
                event.ignore()
                self._is_drag_over = False
                self.update()
        else:
            event.ignore()
            self._is_drag_over = False
            self.update()

    def dragLeaveEvent(self, event):
        self._is_drag_over = False
        self.update()
        super().dragLeaveEvent(event)

    def dropEvent(self, event: QDropEvent):
        self._is_drag_over = False
        self.update() # 重置拖拽悬停状态并重绘
        # 具体文件处理逻辑由子类实现

    def paintEvent(self, event):
        super().paintEvent(event)
        painter = QPainter(self)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)

        pen = QPen()
        if self._is_drag_over:
            pen.setColor(Qt.GlobalColor.darkCyan) # 悬停时颜色
            pen.setWidth(2)
        else:
            pen.setColor(Qt.GlobalColor.lightGray) # 默认颜色
            pen.setWidth(1)
        
        pen.setStyle(Qt.PenStyle.DashLine)
        painter.setPen(pen)
        
        rect = self.rect().adjusted(1, 1, -1, -1)
        painter.drawRoundedRect(rect, 5, 5) # 使用圆角矩形

    def resetWidget(self):
        """重置控件到初始状态"""
        self.clearFileButton.setEnabled(False)


class CustomDropSingleFileWidget(CustomDropFileWidgetBase):
    """ 自定义单文件拖放控件 """
    fileDropped = Signal(str)  # 文件路径
    fileCleared = Signal()  # 清空文件信号

    def __init__(self, parent: QWidget | None = None):
        super().__init__(parent)
        
        self.browseFileButton = PrimaryPushButton(FluentIcon.FOLDER, "浏览文件", self)
        self.browseFileButton.clicked.connect(self._onBrowseFileClicked)
        self.buttonLayout.addWidget(self.browseFileButton)
        self.buttonLayout.addWidget(self.clearFileButton)


    def dragEnterEvent(self, event: QDragEnterEvent):
        mime_data = event.mimeData()
        if mime_data.hasUrls():
            urls = mime_data.urls()
            if len(urls) == 1 and urls[0].isLocalFile():
                if self.canAccept(urls[0].toLocalFile()):
                    event.acceptProposedAction()
                    self._is_drag_over = True
                    self.update()
                    return
        event.ignore()
        self._is_drag_over = False
        self.update()


    def dropEvent(self, event: QDropEvent):
        super().dropEvent(event) # 调用基类处理 _is_drag_over
        mime_data = event.mimeData()
        if mime_data.hasUrls():
            urls = mime_data.urls()
            if len(urls) == 1 and urls[0].isLocalFile():
                file_path = urls[0].toLocalFile()
                if self.canAccept(file_path):
                    self.fileDropped.emit(file_path)
                    self.clearFileButton.setEnabled(True)  # 有文件时启用清空按钮
                    event.acceptProposedAction()
                    return
        event.ignore()

    def _onBrowseFileClicked(self):
        # 构建文件过滤器
        filter_str = ""
        if self.suffixes:
            name_filters = [f"*.{s}" for s in self.suffixes]
            filter_str = f"Supported Files ({' '.join(name_filters)});;All Files (*)"
        
        file_path, _ = QFileDialog.getOpenFileName(
            self, 
            "选择文件", 
            "", # 起始目录，可以后续添加 currentDir 功能
            filter_str
        )
        if file_path and self.canAccept(file_path): # 再次检查以防用户手动输入不支持的类型
            self.fileDropped.emit(file_path)
            self.clearFileButton.setEnabled(True)  # 有文件时启用清空按钮
            
    def _onClearFileClicked(self):
        """清空文件按钮点击事件"""
        if self.suffixes:
            self.setTitle(f"支持的格式：{', '.join(s.upper() for s in self.suffixes)}")
        else:
            self.setTitle("将文件拖到此处")
        self.fileCleared.emit()  # 发送清空文件信号
        self.clearFileButton.setEnabled(False)  # 禁用清空按钮
        
    def resetWidget(self):
        """重置控件到初始状态"""
        super().resetWidget()
        if self.suffixes:
            self.setTitle(f"支持的格式：{', '.join(s.upper() for s in self.suffixes)}")
        else:
            self.setTitle("将文件拖到此处")


class CustomDropMultiFilesWidget(CustomDropFileWidgetBase):
    """ 自定义多文件拖放控件 """
    filesDropped = Signal(list)  # 文件路径列表
    filesCleared = Signal()  # 清空文件信号

    def __init__(self, parent: QWidget | None = None):
        super().__init__(parent)

        self.browseFilesButton = PrimaryPushButton(FluentIcon.FOLDER, "浏览图片", self)
        self.browseFilesButton.clicked.connect(self._onBrowseFilesClicked)
        self.buttonLayout.addWidget(self.browseFilesButton)
        self.buttonLayout.addWidget(self.clearFileButton)
        
        # 如果需要"浏览文件夹"按钮，可以取消下面的注释
        # self.browseFolderButton = PushButton(FluentIcon.FOLDER_ADD, "浏览文件夹", self)
        # self.browseFolderButton.clicked.connect(self._onBrowseFolderClicked)
        # self.buttonLayout.addWidget(self.browseFolderButton)


    def dropEvent(self, event: QDropEvent):
        super().dropEvent(event) # 调用基类处理 _is_drag_over
        mime_data = event.mimeData()
        if mime_data.hasUrls():
            dropped_files = []
            for url in mime_data.urls():
                if url.isLocalFile():
                    file_path = url.toLocalFile()
                    if self.canAccept(file_path):
                        dropped_files.append(file_path)
            
            if dropped_files:
                self.filesDropped.emit(dropped_files)
                self.clearFileButton.setEnabled(True)  # 有文件时启用清空按钮
                event.acceptProposedAction()
            else:
                event.ignore() # 没有可接受的文件
        else:
            event.ignore()

    def _onBrowseFilesClicked(self):
        filter_str = ""
        if self.suffixes:
            name_filters = [f"*.{s}" for s in self.suffixes]
            filter_str = f"Supported Files ({' '.join(name_filters)});;All Files (*)"

        file_paths, _ = QFileDialog.getOpenFileNames(
            self, 
            "选择文件", 
            "", 
            filter_str
        )
        
        accepted_files = []
        if file_paths:
            for fp in file_paths:
                if self.canAccept(fp):
                    accepted_files.append(fp)
        
        if accepted_files:
            self.filesDropped.emit(accepted_files)
            self.clearFileButton.setEnabled(True)  # 有文件时启用清空按钮
            
    def _onClearFileClicked(self):
        """清空文件按钮点击事件"""
        if self.suffixes:
            self.setTitle(f"支持的格式：{', '.join(s.upper() for s in self.suffixes)}")
        else:
            self.setTitle("将文件拖到此处")
        self.filesCleared.emit()  # 发送清空文件信号
        self.clearFileButton.setEnabled(False)  # 禁用清空按钮
        
    def resetWidget(self):
        """重置控件到初始状态"""
        super().resetWidget()
        if self.suffixes:
            self.setTitle(f"支持的格式：{', '.join(s.upper() for s in self.suffixes)}")
        else:
            self.setTitle("将文件拖到此处")